package com.itheima.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/setmeal")
public class SetmealController {


    //注入套餐相关操作服务
    @Autowired
    private SetmealService setmealService;
    //注入套餐关联相关菜品服务
    @Autowired
    private SetmealDishService setmealDishService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;


    /**
     * 保存套餐信息
     *
     * @param setmealDto dto类型
     * @return R
     */
    // @CacheEvict(value = "setmeal",key = "'setmeal_' + #setmealDto.categoryId + '_' + #setmealDto.status")
    @CacheEvict(value = "setmealCache",allEntries = true)
    @PostMapping
    public R<String> saveSetmealInfo(@RequestBody SetmealDto setmealDto) {
        log.info("请求实体类进来了{}", setmealDto);
        setmealService.saveWithDish(setmealDto);
        return R.success("套餐info数据添加成功!!");
    }

    @GetMapping("/page2")
    public R<Page<SetmealDto>> findPageList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize, String name) {
        log.info("分页请求参数page{},pageSize{},name{}", page, pageSize, name);
        //创建分页条件查询对象
        Page<Setmeal> setmealPage = new Page<>(page, pageSize);
        //构建查询条件对象，如有套餐名称，则添加套餐名称模糊查询 并要求对修改时间进行降序排序
        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();
        qw.like(name != null && !"".equals(name), Setmeal::getName, name);
        qw.orderByDesc(Setmeal::getUpdateTime);
        //执行分页查询
        Page<Setmeal> smPage = setmealService.page(setmealPage, qw);
        //组装数据并返回
        Page<SetmealDto> dtoPage = new Page<>();

        //根据分类id条件查询出分类数据并设置name字段值进入dtoPage对象中
        List<SetmealDto> collect = smPage.getRecords().stream().map((item) -> {
            SetmealDto dto = new SetmealDto();
            Long categoryId = item.getCategoryId();
            QueryWrapper<Category> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(0 != categoryId && categoryId != null,
                    Category::getId, categoryId);
            Category category = categoryService.getOne(wrapper);
            dto.setCategoryName(category.getName());
            BeanUtils.copyProperties(item, dto);
            return dto;
        }).collect(Collectors.toList());

        dtoPage.setRecords(collect);
        BeanUtils.copyProperties(smPage, dtoPage, "records");
        return R.success(dtoPage);
    }

    @GetMapping("/page")
    public R<Page<SetmealDto>> findPage(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize, String name) {
        log.info("分页请求参数page{},pageSize{},name{}", page, pageSize, name);


        Page<SetmealDto> dtoPage = setmealService.findPage(page, pageSize, name);

        return R.success(dtoPage);
    }
    @CacheEvict(value = "setmealCache" ,allEntries = true) //清除setmealCache名称下,所有的缓存数据
    @DeleteMapping
    public R<String> delete(@RequestParam List<Long> ids) {
        log.info("ids:[{}]", ids);

        setmealService.removeWithDish(ids);
        return R.success("单个/批量删除套餐成功!");
    }

    /**
     * 套餐info查询根据id
     */
    @GetMapping("/{id}")
    public R<SetmealDto> selSetmealById(@PathVariable Long id) {
        log.info("将返回id为{}的套餐数据", id);
        SetmealDto dto = setmealService.getSetmealData(id);
        return R.success(dto);
    }

    /**
     * 套餐数据修改
     */
    @CacheEvict(value = "setmealCache",allEntries = true)
    @PutMapping
    public R<String> updSetmealData(@RequestBody SetmealDto setmealDto) {

        setmealService.modifyPackageData(setmealDto);
        return R.success("修改套餐成功! !");
    }

    /**
     * 单个\批量修改套餐状态
     */
    @PostMapping("/status/{state}")
    public R<String> stateBatchUpdate(@PathVariable int state, @RequestParam Long[] ids) {
        log.info("修改id{}状态值至{}..", ids, state);
        setmealService.modifyState(state, ids);
        return R.success("套餐状态修改成功!");
    }

    /**
     * 移动端套餐菜品查询接口
     */
    @Cacheable(value = "setmealCache",key = "'setmeal_' + #categoryId + '_' + #status")
    @GetMapping("/list")
    public R<List<SetmealDto>> getSetmealDto(Long categoryId, Integer status) {
        log.info("前端传入参数cateId:{},stateVal:{}", categoryId, status);
        //根据传入的分类id查询出setmeal表中所属分类下的套餐数据
        LambdaQueryWrapper<Setmeal> qw = new LambdaQueryWrapper<>();
        qw.eq(Setmeal::getCategoryId, categoryId);
        qw.eq(Setmeal::getStatus, status);
        qw.orderByDesc(Setmeal::getUpdateTime);
        List<Setmeal> setmeals = setmealService.list(qw);
        ArrayList<SetmealDto> setmealDtos = new ArrayList<>();
        //每一条套餐数据中会包含多种菜品
        for (int i = 0; i < setmeals.size(); i++) {
            SetmealDto dto = new SetmealDto();
            BeanUtils.copyProperties(setmeals.get(i), dto);  //属性copy
            dto.setCategoryName(categoryService.getById(dto.getCategoryId()).getName());
            LambdaQueryWrapper<SetmealDish> lqw = new LambdaQueryWrapper<>();
            lqw.eq(SetmealDish::getSetmealId, dto.getId());
            List<SetmealDish> setmealDishList = setmealDishService.list(lqw);
            dto.setSetmealDishes(setmealDishList);
            setmealDtos.add(dto);
        }
        return R.success(setmealDtos);
    }

    @GetMapping("/dish/{id}")
    public R<List<DishDto>> findDishBySetmealId(@PathVariable(name = "id") Long setmealId) {
        log.info("传入套餐ID参数:{}",setmealId);
        LambdaQueryWrapper<SetmealDish> qw = new LambdaQueryWrapper<>();
        qw.eq(SetmealDish::getSetmealId,setmealId);
        List<SetmealDish> setmealDishes = setmealDishService.list(qw);

        List<DishDto> dishDtos = new ArrayList<>();
        for (SetmealDish setmealDish : setmealDishes) {
            Dish dish = dishService.getById(setmealDish.getDishId());
            DishDto dto = new DishDto();
            BeanUtils.copyProperties(dish, dto);
            LambdaQueryWrapper<DishFlavor> dfqw = new LambdaQueryWrapper<>();
            dfqw.eq(DishFlavor::getDishId, dto.getId());
            List<DishFlavor> flavorList = dishFlavorService.list(dfqw);
            dto.setFlavors(flavorList);
            dto.setCategoryName(categoryService.getById(dto.getCategoryId()).getName());
            dto.setCopies(setmealDish.getCopies());
            dishDtos.add(dto);
        }

        //遍历封装了菜品信息的集合
        return R.success(dishDtos);
    }
}
